package com.jxtc.enterprise.employee.serviceImpl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.fastjson.JSONObject;
import com.jxtc.enterprise.common.constants.PrinterTypeEnum;
import com.jxtc.enterprise.common.entity.Company;
import com.jxtc.enterprise.common.entity.User;
import com.jxtc.enterprise.common.entity.VipUser;
import com.jxtc.enterprise.common.entity.VipUserOrderPayment;
import com.jxtc.enterprise.common.exception.InsertFailureException;
import com.jxtc.enterprise.common.exception.ModifyFailureException;
import com.jxtc.enterprise.common.mapper.CompanyMapper;
import com.jxtc.enterprise.common.mapper.UserMapper;
import com.jxtc.enterprise.common.mapper.VipUserMapper;
import com.jxtc.enterprise.common.mapper.VipUserOrderPaymentMapper;
import com.jxtc.enterprise.common.utils.DateTimeUtil;
import com.jxtc.enterprise.common.utils.FeieYunPrinterApi;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Slf4j
@RequiredArgsConstructor
public class VipUserMealServiceImpl {

    private final UserMapper userMapper;
    private final CompanyMapper companyMapper;
    private final VipUserMapper vipUserMapper;
    private final VipUserOrderPaymentMapper vipUserOrderPaymentMapper;

    @Transactional(rollbackFor = Exception.class)
    public int createVipUserOrder(String vipUserId, String requestIdForDebug) {
        // 1. 查询客户信息
        VipUser vipUser = vipUserMapper.selectById(vipUserId);
        if (vipUser == null) {
            log.warn("requestId {}, 餐券不存在, vipUserId:{}", requestIdForDebug, vipUserId);
            throw new IllegalArgumentException("餐券不存在");
        }

        Company serviceCompany = companyMapper.selectById(vipUser.getServiceEmployeeCompanyId());
        if (serviceCompany == null) {
            log.error("requestId {}, 服务客户的员工所在公司 ID 在 Company 表中不存在, vipUserId:{}, companyId:{}", requestIdForDebug, vipUserId, vipUser.getServiceEmployeeCompanyId());
            throw new IllegalArgumentException("发放餐券的公司不存在，请联系管理员排查");
        }

        // 2. 判断餐券是否已用完
        int leftCreateOrderCount = vipUser.getLeftCreateOrderCount();
        if (leftCreateOrderCount <= 0) {
            log.warn("requestId {}, 餐券已用完, vipUserId:{}", requestIdForDebug, vipUserId);
            throw new IllegalArgumentException("该餐券下单次数已用完");
        }

        // 3. 根据客户信息创建客户餐订单记录
        VipUserOrderPayment vipOrderPaymentRecord = createVipOrderPaymentRecord(vipUser, serviceCompany, requestIdForDebug);

        // 4. 打印客户餐小票
        printVipOrder(vipUser, vipOrderPaymentRecord, serviceCompany, requestIdForDebug);

        // 5. 更新餐券信息，并返回剩余点餐次数
        return updateVipUserLeftCreateOrderCount(vipUser, requestIdForDebug);
    }

    private VipUserOrderPayment createVipOrderPaymentRecord(VipUser vipUser, Company serviceCompany, String requestIdForDebug) {
        VipUserOrderPayment entity = new VipUserOrderPayment();
        entity.setUserId(vipUser.getId());
        entity.setEmployeeId(vipUser.getServiceEmployeeId());
        entity.setCompanyId(vipUser.getServiceEmployeeCompanyId());
        entity.setUsername(vipUser.getUsername());
        entity.setPhone(vipUser.getPhone());

        String todayDate = DateTimeUtil.getCurrentDate();
        entity.setDateFlag(todayDate);

        // 设置客户餐名称及价格，通过公司表中配置的数据赋值
        entity.setMealSetName(serviceCompany.getVipUserMealSetName());
        entity.setMealSetPrice(serviceCompany.getVipUserMealSetPrice());

        int insertCount = vipUserOrderPaymentMapper.insert(entity);
        if (insertCount != 1) {
            log.error("requestId {}, 创建客户餐订单记录失败, VipUserOrderPayment: {}", requestIdForDebug, JSONObject.toJSONString(entity));
            throw new InsertFailureException("创建客户餐订单失败，请稍后重试");
        }

        return entity;
    }

    private void printVipOrder(VipUser vipUser, VipUserOrderPayment vipOrderPaymentRecord, Company company, String requestIdForDebug) {
        int createdOrderCount = vipUser.getFoodCount() - vipUser.getLeftCreateOrderCount() + 1;

        User employee = userMapper.selectById(vipUser.getServiceEmployeeId());

        log.info("requestId {}, ========== 打印客户餐小票 ==========", requestIdForDebug);
        log.info("requestId {}, 打印机 SN: {}", requestIdForDebug, company.getVipUserPrinterSn());
        log.info("requestId {}, 打印机类型: {} (1: 贴纸, 2: 小票)", requestIdForDebug, company.getVipUserPrinterType());
        log.info("requestId {}, 客户名称: {}", requestIdForDebug, vipOrderPaymentRecord.getUsername());
        log.info("requestId {}, 客户手机号: {}", requestIdForDebug, vipOrderPaymentRecord.getPhone());
        log.info("requestId {}, 套餐名称: {}", requestIdForDebug, vipOrderPaymentRecord.getMealSetName());
        log.info("requestId {}, 餐券已使用次数: {}", requestIdForDebug, createdOrderCount);
        log.info("requestId {}, 餐券可使用次数: {}", requestIdForDebug, vipUser.getFoodCount());
        log.info("requestId {}, 公司名称: {}", requestIdForDebug, company.getName());
        log.info("requestId {}, 接待员工姓名: {}", requestIdForDebug, employee.getUsername());
        log.info("requestId {}, 车型: {}", requestIdForDebug, vipUser.getCarType());
        log.info("requestId {}, =================================", requestIdForDebug);

        String orderCount = String.format("%d/%d", createdOrderCount, vipUser.getFoodCount());
        String createVipOrderTime = LocalDateTimeUtil.format(vipOrderPaymentRecord.getCreateTime(), DatePattern.NORM_DATETIME_PATTERN);

        // 调用飞鹅服务打印客户餐小票
        try {
            Integer vipUserPrinterType = company.getVipUserPrinterType();
            String responseBodyStr;
            if (vipUserPrinterType.equals(PrinterTypeEnum.XIAO_PIAO_PRINTER.getTypeCode())) {
                // 如果该公司配置的客户餐打印类型是【小票打印机】
                responseBodyStr = FeieYunPrinterApi.printVipUserOrderTicketTemplate(
                        company.getVipUserPrinterSn(),
                        vipOrderPaymentRecord.getUsername(),
                        vipOrderPaymentRecord.getPhone(),
                        vipOrderPaymentRecord.getMealSetName(),
                        company.getName(),
                        employee.getUsername(),
                        vipUser.getCarType(),
                        vipUser.getVisitorType(),
                        orderCount,
                        createVipOrderTime
                );
            } else {
                // 否则，使用贴纸打印机进行打印小票
                responseBodyStr = FeieYunPrinterApi.printVipUserOrderLabelTemplate(
                        company.getVipUserPrinterSn(),
                        vipOrderPaymentRecord.getUsername(),
                        vipOrderPaymentRecord.getPhone(),
                        vipOrderPaymentRecord.getMealSetName(),
                        company.getName(),
                        employee.getUsername(),
                        vipUser.getCarType(),
                        orderCount,
                        createVipOrderTime
                );
            }

            JSONObject responseBody = JSONObject.parseObject(responseBodyStr);
            Integer retCode = responseBody.getInteger("ret");
            if (retCode == 0) {
                log.info("requestId {}, 调用云打印机打印客户餐小票成功", requestIdForDebug);
                // 启动异步线程以轮询的方式，调用用云打印机接口，查询订单是否打印完成 (todo 改成线程池)
            } else {
                String errMsg = responseBody.getString("msg");
                log.error("requestId {}, 调用云打印机打印标签失败，失败原因: {}", requestIdForDebug, errMsg);
            }
        } catch (Throwable ex) {
            log.error("requestId {}, 打印异常，客户餐订单 ID: {}", requestIdForDebug, vipOrderPaymentRecord.getId(), ex);
        }
    }

    private int updateVipUserLeftCreateOrderCount(VipUser vipUser, String requestIdForDebug) {
        int leftCount = vipUser.getLeftCreateOrderCount() - 1;

        VipUser vipUserUpdate = new VipUser();
        vipUserUpdate.setId(vipUser.getId());
        vipUserUpdate.setLeftCreateOrderCount(leftCount);
        int updateCount = vipUserMapper.updateById(vipUserUpdate);
        if (updateCount != 1) {
            log.error("requestId {}, 更新餐券信息失败, VipUser: {}", requestIdForDebug, JSONObject.toJSONString(vipUserUpdate));
            throw new ModifyFailureException("更新餐券信息失败，请稍后重试");
        }

        return leftCount;
    }


}
